<?php
declare(strict_types=1);

namespace app\install\controller;

use app\common\utils\JsonResponse;
use think\facade\Db;
use think\facade\Request;

class Index
{
    // 安装锁文件
    protected $lockFile;

    // 错误信息
    protected $error = '';
    
    /**
     * 获取错误信息
     * @return string
     */
    protected function getError()
    {
        return $this->error;
    }
    
    /**
     * 设置错误信息
     * @param string $error
     */
    protected function setError($error)
    {
        $this->error = $error;
    }

    public function __construct()
    {
        // 检查是否已安装
        $this->lockFile = root_path() . 'install.lock';
        if (file_exists($this->lockFile) && request()->action() !== 'status') {
            $this->setError('系统已安装，如需重新安装请删除“install.lock”文件');
        }
    }
    
    /**
     * 安装首页
     */
    public function index()
    {
        $error = $this->getError();
        $html = file_get_contents(root_path() . 'app/install/view/index/index.html');

        return response($html)->contentType('text/html')->header(['X-Error' => urlencode($error)]);
    }
    
    /**
     * 检查安装环境
     */
    public function checkenv()
    {
        $items = [
            'php' => [
                'name' => 'PHP版本',
                'required' => '8.0.0',
                'current' => PHP_VERSION,
                'result' => version_compare(PHP_VERSION, '8.0.0', '>=')
            ],
            'extensions' => [
                [
                    'name' => 'PDO',
                    'required' => '启用',
                    'current' => extension_loaded('pdo') ? '已启用' : '未启用',
                    'result' => extension_loaded('pdo')
                ],
                [
                    'name' => 'JSON',
                    'required' => '启用',
                    'current' => extension_loaded('json') ? '已启用' : '未启用',
                    'result' => extension_loaded('json')
                ],
                [
                    'name' => 'OpenSSL',
                    'required' => '启用',
                    'current' => extension_loaded('openssl') ? '已启用' : '未启用',
                    'result' => extension_loaded('openssl')
                ],
                [
                    'name' => 'PDO_MySQL',
                    'required' => '启用',
                    'current' => extension_loaded('pdo_mysql') ? '已启用' : '未启用',
                    'result' => extension_loaded('pdo_mysql')
                ]
            ],
            'dirs' => [
                [
                    'name' => 'runtime目录',
                    'required' => '可写',
                    'current' => is_writable(root_path() . 'runtime') ? '可写' : '不可写',
                    'result' => is_writable(root_path() . 'runtime')
                ],
                [
                    'name' => '.env文件',
                    'required' => '可写',
                    'current' => is_writable(root_path() . '.env') ? '可写' : '不可写',
                    'result' => is_writable(root_path() . '.env')
                ],
                [
                    'name' => 'config目录',
                    'required' => '可写',
                    'current' => is_writable(config_path()) ? '可写' : '不可写',
                    'result' => is_writable(config_path())
                ]
            ]
        ];
        
        return JsonResponse::success($items);
    }
    
    /**
     * 检查数据库连接
     */
    public function checkdb()
    {
        $params = Request::post();
        
        try {
            $dsn = "mysql:host={$params['db_hostname']};port={$params['db_hostport']}";
            $conn = new \PDO($dsn, $params['db_username'], $params['db_password']);
            $conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
            return JsonResponse::success();
        } catch (\PDOException $e) {
            return JsonResponse::error($e->getMessage());
        }
    }
    
    /**
     * 创建数据库
     */
    public function createdb()
    {
        $params = Request::post();
        
        try {
            $dsn = "mysql:host={$params['db_hostname']};port={$params['db_hostport']}";
            $conn = new \PDO($dsn, $params['db_username'], $params['db_password']);
            $conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
            
            // 创建数据库
            $sql = "CREATE DATABASE IF NOT EXISTS `{$params['db_database']}` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;";
            $conn->exec($sql);
            
            // 读取.env模板文件
            $envFile = root_path() . '.example.env';
            if (!file_exists($envFile)) {
                return JsonResponse::error('.env模板文件不存在');
            }
            
            // 读取模板内容
            $env = file_get_contents($envFile);
            
            // 替换数据库配置
            $env = preg_replace('/DB_TYPE\s*=\s*.*/', "DB_TYPE = {$params['db_type']}", $env);
            $env = preg_replace('/DB_HOST\s*=\s*.*/', "DB_HOST = {$params['db_hostname']}", $env);
            $env = preg_replace('/DB_PORT\s*=\s*.*/', "DB_PORT = {$params['db_hostport']}", $env);
            $env = preg_replace('/DB_NAME\s*=\s*.*/', "DB_NAME = {$params['db_database']}", $env);
            $env = preg_replace('/DB_USER\s*=\s*.*/', "DB_USER = {$params['db_username']}", $env);
            $env = preg_replace('/DB_PASS\s*=\s*.*/', "DB_PASS = {$params['db_password']}", $env);
            $env = preg_replace('/DB_PREFIX\s*=\s*.*/', "DB_PREFIX = {$params['db_prefix']}", $env);
            
            // 写入新的.env文件
            file_put_contents(root_path() . '.env', $env);
            
            return JsonResponse::success();
        } catch (\PDOException $e) {
            return JsonResponse::error($e->getMessage());
        }
    }
    
    /**
     * 导入数据库
     */
    public function importdb()
    {
        $params = Request::post();
        
        try {
            // 读取SQL文件
            $sqlFile = root_path() . 'install/database.sql';
            if (!file_exists($sqlFile)) {
                return JsonResponse::error('SQL文件不存在');
            }
            
            // 获取SQL内容
            $sql = file_get_contents($sqlFile);
            
            // 替换表前缀
            $defaultPrefix = 'ml_';  // SQL文件中的默认前缀
            $newPrefix = $params['db_prefix'] ?? 'ml_';  // 用户设置的前缀
            if ($defaultPrefix != $newPrefix) {
                $sql = str_replace(
                    [
                        "CREATE TABLE `{$defaultPrefix}",
                        "INSERT INTO `{$defaultPrefix}",
                        "REFERENCES `{$defaultPrefix}",
                        "ALTER TABLE `{$defaultPrefix}"
                    ],
                    [
                        "CREATE TABLE `{$newPrefix}",
                        "INSERT INTO `{$newPrefix}",
                        "REFERENCES `{$newPrefix}",
                        "ALTER TABLE `{$newPrefix}"
                    ],
                    $sql
                );
            }
            
            // 分割SQL语句
            $sql = str_replace("\r", "\n", $sql);
            $sql = explode(";\n", $sql);
            
            // 执行SQL语句
            Db::startTrans();
            try {
                foreach ($sql as $value) {
                    $value = trim($value);
                    if (!empty($value)) {
                        Db::execute($value);
                    }
                }
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }
            
            return JsonResponse::success();
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }
    
    /**
     * 创建管理员
     */
    public function createadmin()
    {
        $params = Request::post();
        
        try {
            // 验证密码
            if (empty($params['admin_password'])) {
                return JsonResponse::error('密码不能为空');
            }
            
            // 生成密码盐
            $salt = substr(md5(uniqid()), 0, 6);
            $password = md5($params['admin_password'] . $salt);
            
            // 创建管理员
            Db::startTrans();
            try {
                // 添加管理员
                $adminId = Db::name('admin')->insertGetId([
                    'username' => $params['admin_username'],
                    'password' => $password,
                    'salt' => $salt,
                    'nickname' => '超级管理员',
                    'status' => 1,
                    'create_time' => time(),
                    'update_time' => time()
                ]);
                
                // 添加超级管理员角色
                $roleId = Db::name('role')->insertGetId([
                    'name' => '超级管理员',
                    'code' => 'super_admin',
                    'status' => 1,
                    'create_time' => time(),
                    'update_time' => time()
                ]);
                
                // 关联管理员和角色
                Db::name('admin_role')->insert([
                    'admin_id' => $adminId,
                    'role_id' => $roleId
                ]);
                
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }
            
            return JsonResponse::success();
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }
    
    /**
     * 完成安装
     */
    public function complete()
    {
        try {
            // 生成安装锁文件
            file_put_contents($this->lockFile, date('Y-m-d H:i:s'));
            
            // 修改配置文件权限
            @chmod(config_path() . 'database.php', 0644);
            @chmod(root_path() . '.env', 0644);
            
            return JsonResponse::success();
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage());
        }
    }
    
    /**
     * 获取安装状态
     */
    public function status()
    {
        return JsonResponse::success([
            'installed' => file_exists($this->lockFile)
        ]);
    }
} 